﻿using HMS.Contracts.Entities;
using HMS.Core.Abstractions;
using HMS.Core.DataProtocol;
using Microsoft.Data.SqlClient;

namespace HMS.Services.Impl;

public class HotelConfigService : IHotelConfigService
{
    private readonly DbContext _context;
    private readonly ITenantService _tenantService;

    public HotelConfigService(DbContext context, ITenantService tenantService)
    {
        _context = context;
        _tenantService = tenantService;
    }

    public async Task<OperationalResult> AddAsync(HotelConfig.CreateRequest createRequest, CancellationToken cancellationToken)
    {
        var result = new OperationalResult();

        try
        {
            var tenant = _tenantService.Tenant;

            var config = new HotelConfig()
            {
                Name = createRequest.Name,
                LegalPerson = createRequest.LegalPerson,
                License = tenant.License,
                LicenseKey = tenant.LicenseKey
            };

            await _context.Set<HotelConfig>().AddAsync(config, cancellationToken);

            var affectedRows = await _context.SaveChangesAsync(cancellationToken);

            if (affectedRows > 0)
            {
                return result;
            }
            else
            {
                result.Status = OperationalResult.FAILURE;

                result.Message = "新增失败";
            }
        }
        catch (Exception error)
        {
            result.Status = OperationalResult.ERROR;

            result.Message = error.ToString();
        }

        return result;
    }

    public async Task<OperationalResult<HotelConfig.GetResponse>> GetAsync(int Id, CancellationToken cancellationToken)
    {
        var result = new OperationalResult<HotelConfig.GetResponse>();

        try
        {
            var hotelconfig = await _context.Set<HotelConfig>()
                .Where(x => x.Id.Equals(Id))
                .AsNoTracking()
                .FirstOrDefaultAsync(cancellationToken);

            if (hotelconfig is not null)
            {
                result.Data = GetHotelConfigGetResponse(hotelconfig);

                result.Status = OperationalResult.SUCCESS;
            }
            else
            {
                result.Status = OperationalResult.FAILURE;

                result.Message = "0 row affected.";
            }
        }
        catch (Exception error)
        {
            result.Status = OperationalResult.ERROR;

            result.Message = error.ToString();
        }

        return result;
    }

    public async Task<ListResult<HotelConfig.GetListResponse>> GetListAsync(CancellationToken cancellationToken)
    {
        var result = new ListResult<HotelConfig.GetListResponse>();

        try
        {
            var hotelconfig = await _context.Set<HotelConfig>()
                .AsNoTracking()
                .ToListAsync(cancellationToken);

            result.Data = hotelconfig.Select(x => GetHotelConfigGetListResponse(x));

            result.Status = OperationalResult.SUCCESS;
        }
        catch (SqlException)
        {
            throw;
        }
        catch (Exception error)
        {
            result.Status = OperationalResult.ERROR;

            result.Message = error.Message;
        }

        return result;
    }

    private HotelConfig.GetResponse GetHotelConfigGetResponse(HotelConfig hotelconfig)
    {
        var model = new HotelConfig.GetResponse
        {
            Name = hotelconfig.Name,
            LegalPerson = hotelconfig.LegalPerson,
            License = hotelconfig.License,
            LicenseKey = hotelconfig.LicenseKey,
            Id = hotelconfig.Id,
            CreateDate = hotelconfig.CreateDate
        };

        return model;
    }

    private HotelConfig.GetListResponse GetHotelConfigGetListResponse(HotelConfig hotelconfig)
    {
        var model = new HotelConfig.GetListResponse
        {
            Name = hotelconfig.Name,
            LegalPerson = hotelconfig.LegalPerson,
            License = hotelconfig.License,
            LicenseKey = hotelconfig.LicenseKey,
            Id = hotelconfig.Id,
            CreateDate = hotelconfig.CreateDate
        };

        return model;
    }
}
